import {computed, designPage, reactive, SimpleFunction, useRefs} from "@peryl/react-compose";
import {$ai, $dialog, $message, Box, Button, Checkbox, DatePicker, Empty, Form, FormItem, i18n, iAnotherRule, Icon, Input, InputGroup, InputNumber, PageCard, PageCardContent, PageCardTitle, Radio, RadioGroup, Select, SelectOption, Tooltip, VirtualList} from "plain-design";
import {PlainObject} from "@peryl/utils/event";

export default designPage(() => {

  const { refs, onRef } = useRefs({ form: Form });

  const state = reactive({
    useTextInput: false,
    columns: 3,
    list: [
      {
        "OrderID": "ORD20250419004",
        "CustomerID": "CUS004",
        "CustomerPhone": "13312348765",
        "CustomerEmail": "lucy@example.com",
        "OrderTime": "2025-04-19 08:20:00",
        "CustomerName": "露西"
      },
      {
        "OrderID": "ORD20250419005",
        "CustomerID": "CUS005",
        "CustomerPhone": "15598761234",
        "CustomerEmail": "jack@example.com",
        "OrderTime": "2025-04-19 11:35:00",
        "CustomerName": "杰克"
      },
      {
        "OrderID": "ORD20250419006",
        "CustomerID": "CUS006",
        "CustomerPhone": "17756782345",
        "CustomerEmail": "lily@example.com",
        "OrderTime": "2025-04-19 15:50:00",
        "CustomerName": "莉莉"
      }
    ] as PlainObject[]
  });

  const selectOptions: { label: string, val: string }[] = [
    { label: i18n.$intl('page.virtualFormMultiplePage.selectOptions.new').d("新建"), val: 'new' },
    { label: i18n.$intl('page.virtualFormMultiplePage.selectOptions.to_pay').d("待支付"), val: 'to_pay' },
    { label: i18n.$intl('page.virtualFormMultiplePage.selectOptions.to_ship').d("待发货"), val: 'to_ship' },
    { label: i18n.$intl('page.virtualFormMultiplePage.selectOptions.cancel').d("已取消"), val: 'cancel' },
  ];

  /*根据类型动态渲染编辑表单组件*/
  const renderHandler: Record<iFieldMeta['type'], iFieldRender> = {
    input: ({ field, formData }) => {
      return <Input v-model={formData[field]}/>;
    },
    select: ({ field, formData }) => {
      return <Select v-model={formData[field]}>{selectOptions.map(i => (<SelectOption label={i.label} key={i.val} val={i.val}/>))}</Select>;
    },
    number: ({ field, formData }) => {
      return <InputNumber v-model={formData[field]}/>;
    },
    date: ({ field, formData }) => {
      return <DatePicker v-model={formData[field]}/>;
    },
    textarea: ({ field, formData }) => {
      return <Input textarea v-model={formData[field]}/>;
    },
    radio: ({ field, formData }) => {
      return (
        <RadioGroup v-model={formData[field]} itemWidth={'50%'}>
          <Radio label="是" val="Y"/>
          <Radio label="否" val="N"/>
        </RadioGroup>
      );
    },
  };

  const verticalLabel = i18n.state.currentLang === 'en-us';

  type iFieldRender = (data: { field: string, formData: any }) => any

  interface iFieldMeta {
    type: 'input' | 'select' | 'date' | 'number' | 'textarea' | 'radio',
    label: string,
    field: string,
    required?: boolean,
    rule?: Omit<iAnotherRule, 'label' | 'field'>,
    render?: iFieldRender,
  }

  const fields: iFieldMeta[] = [
    { type: 'input', label: i18n.$intl('page.virtualFormGroupPage.fields.OrderID').d('订单编号'), field: 'OrderID', required: true, },
    { type: 'input', label: i18n.$intl('page.virtualFormGroupPage.fields.CustomerID').d('客户编号'), field: 'CustomerID', required: true, },
    {
      type: 'input', label: i18n.$intl('page.virtualFormGroupPage.fields.CustomerName').d('客户姓名'), field: 'CustomerName',
      required: true,
      render: ({ field, formData }) => {
        return state.useTextInput ? (
          <span>{formData[field]}</span>
        ) : (
          <InputGroup>
            <Input v-model={formData[field]} v-slots={{
              suffix: () => (
                <Tooltip message={i18n.$intl('page.virtualFormGroupPage.customerNameTips').d("不为空则客户电话、客户邮箱必填")}>
                  <span><Icon icon="pi-info-circle-fill"/></span>
                </Tooltip>
              )
            }}/>
            <Button label={i18n.$intl('page.virtualFormGroupPage.customRenderField').d("自定义渲染字段")}/>
          </InputGroup>
        );
      },
    },
    { type: 'input', label: i18n.$intl('page.virtualFormGroupPage.fields.CustomerPhone').d('客户电话'), field: 'CustomerPhone', required: true, },
    { type: 'input', label: i18n.$intl('page.virtualFormGroupPage.fields.CustomerEmail').d('客户邮箱'), field: 'CustomerEmail', required: true, },
    { type: 'date', label: i18n.$intl('page.virtualFormGroupPage.fields.OrderTime').d('下单时间'), field: 'OrderTime', required: true, },
  ];

  const formRules = computed((): { allRules: iAnotherRule[], itemRules: iAnotherRule[][] } => {
    const ret: iAnotherRule[][] = [];
    state.list.forEach((item, index) => {
      const retItem: iAnotherRule[] = [];
      ret.push(retItem);
      fields.forEach(field => {
        if (field.required) {
          retItem.push({
            label: field.label,
            field: field.field + index,
            required: true,
            valueGetter: () => item[field.field],
            message: `第${index + 1}条记录 ${field.label} 校验不通过，不能为空`,
          });
        }
      });
    });
    return {
      allRules: ret.flat(1),
      itemRules: ret.map(retItem => {
        return retItem.map(item => {
          return {
            ...item,
            message: undefined,
          };
        });
      })
    };
  });

  const save = async () => {
    await refs.form?.validate();
    $message.success(i18n.$intl('page.virtualFormGroupPage.validateSuccess').d('保存成功!'));
  };

  const create = () => {
    state.list.push({} as PlainObject);
  };

  const clear = () => {
    state.list = [];
  };

  const removeItem = (index: number) => {state.list.splice(index, 1);};

  const openAiChat = async () => {
    const systemPrompt = `
       你是一名专业的自然语言分析师，需要你帮我将用户的输入转化为表单数据对象数组，目前支持的字段如下所示：
       ${fields.map(field => `{label:"${field.label}", field:"${field.field}"}`).join('\n')}

       label是字段的显示名称，field是字段的标识，；比如用户提供的内容为“${fields[0].label}: 用户提供的值”，
       那么你返回的表单数据对象就得用这个字段标识以及用户提供的值保存在表单数据对象中，比如“{${fields[0].field}: "用户提供的值"}”
       如果这个字段是日期值，那么需要你将日期字符串格式化为YYYY-MM-DD；

       注意的是，最后你返回的数据格式为“序号.字段:字段值”，数据示例如下所示，0开头表示第一条数据，1开头表示第二条数据；以此类推：

       0.OrderID:解析OrderID得到的值
       0.CustomerID:解析CustomerID得到的值
       0.CustomerName:解析CustomerName得到的值
       1.OrderID:解析OrderID得到的值
       1.CustomerID:解析CustomerID得到的值
       1.CustomerName:解析CustomerName得到的值
      `;

    // console.log(systemPrompt)

    let closeDialog: undefined | SimpleFunction = $dialog({
      title: "智能填写",
      editType: 'textarea',
      editRequired: true,
      confirmButton: true,
      cancelButton: true,
      disableCancelOnClickMask: true,
      handleConfirm: async data => {
        state.list = [];
        const formProxyList = state.list;

        const handleFullText = (fullText: string) => {
          /*只处理最后两行*/
          let list = fullText.split('\n').slice(-2);
          list.forEach(item => {
            console.log(item);

            const dotIndex = item.indexOf('.');
            if (dotIndex === -1) {
              /*缺少"."可能是流式数据还没有完整，不做处理*/
              return;
            }
            const _num = item.slice(0, dotIndex);
            const commonIndex = item.indexOf(':');
            if (commonIndex === -1) {
              /*缺少":"可能是流式数据还没有完整，不做处理*/
              return;
            }
            const key = item.slice(dotIndex + 1, commonIndex);
            const val = item.slice(commonIndex + 1);
            const num = Number(_num);

            console.log({ item, key, val, num });

            if (isNaN(num)) {return;}
            if (formProxyList[num] == null) {
              formProxyList.splice(num, 0, {});
              if (!!closeDialog) {
                closeDialog();
                closeDialog = undefined;
              }
            }
            const formProxyRow = formProxyList[num];
            console.log({ formProxyRow, formProxyList, num, });
            formProxyRow![key] = val;
          });
        };

        await $ai.chatStream({
          messages: [
            { role: 'system', content: systemPrompt },
            { role: 'user', content: data.editValue as any }
          ],
          onReceiving: ({ fullText }) => {handleFullText(fullText);},
          onFinish: () => {console.log(state.list);},
        });
      }
    });
  };

  return () => (
    <PageCard full style={{ backgroundColor: 'transparent' }}>
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%', backgroundColor: 'transparent', padding: '0' }}>
        <Box className="mb">
          <PageCard>
            <PageCardTitle title={i18n.$intl('page.virtualFormGroupPage.pageTitle', { val: state.list.length }).d(`总共${state.list.length}个分组`)}>
              <Checkbox label={i18n.$intl('page.virtualFormGroupPage.pureText').d("纯文本")} v-model={state.useTextInput}/>
              <Button label="AI填写" onClick={openAiChat}/>
              <Button label={i18n.$it('base.clear').d("清空")} onClick={clear}/>
              <Button label={i18n.$it('base.edit.create').d("新建")} onClick={create}/>
              <Button label={i18n.$it('base.edit.save').d("保存")} onClick={save} mode="fill"/>
            </PageCardTitle>
          </PageCard>
        </Box>
        {!!state.list.length ? (
          <div style={{ flex: 1, position: 'relative', overflow: 'hidden', }}>
            <div style={{ position: 'absolute', inset: '0' }}>
              <div style={{ display: 'inline-block', width: '100%', height: '100%', padding: '0', }}>
                <Form
                  ref={onRef.form}
                  full
                  inputMode={state.useTextInput ? 'text' : undefined}
                  verticalLabel={verticalLabel}
                  labelWidth={verticalLabel ? 20 : 150}
                  validateMessagePosition="bottom-right"
                  anotherRules={formRules.value.allRules}
                >
                  <VirtualList
                    data={state.list}
                    size={300}
                    dynamicSize
                    v-slots={{
                      default: ({ item, vid, index: itemIndex }) => {
                        return (
                          <Box data-vid={vid} key={vid} className="pb">
                            {(() => {
                              const typeField = fields;
                              return (
                                <PageCard>
                                  <PageCardTitle title={`#${itemIndex + 1}`}>
                                    <Button icon="pi-delete" onClick={() => removeItem(itemIndex)}/>
                                  </PageCardTitle>
                                  <PageCardContent>
                                    {typeField.map((field) => (
                                      <div style={{ width: field.type === 'textarea' ? '100%' : `calc(100% / ${state.columns})`, display: 'inline-block' }} key={field.field}>
                                        <FormItem
                                          labelWidth={verticalLabel ? undefined : "200"}
                                          field={field.field + itemIndex}
                                          label={field.label}
                                          rules={formRules.value.itemRules[itemIndex]?.filter(i => i.field === (field.field + itemIndex))}
                                        >
                                          {field.render ?
                                            field.render({ field: field.field, formData: item })
                                            : renderHandler[field.type]({ field: field.field, formData: item })}
                                        </FormItem>
                                      </div>
                                    ))}
                                  </PageCardContent>
                                </PageCard>
                              );
                            })()}
                          </Box>
                        );
                      }
                    }}
                  />
                </Form>
              </div>
            </div>
          </div>
        ) : (<Empty noData/>)}
      </div>
    </PageCard>
  );

});
